/*
 * @Date: 2022-08-01 22:59:59
 * @LastEditors: Wangjun
 * @LastEditTime: 2023-03-17 18:41:48
 * @FilePath: \golib\nat\nat.go
 * @Description:
 */
package nat

import (
	"io"
	"net"
	"time"

	"gitee.com/haodreams/golib/logs"
	"gitee.com/haodreams/libs/routine"
)

// buffer 的大小
var bufSize = 1500

func SetNatBufSize(size int) {
	bufSize = size
}

// NatTCP 运行nat服务
func NatConn(wlan, lan net.Conn, show bool) {
	wlan.SetReadDeadline(time.Time{})
	lan.SetReadDeadline(time.Time{})
	if show {
		logs.Info(lan.RemoteAddr(), "<====>", wlan.RemoteAddr(), "OK")
		defer func() {
			logs.Info(lan.RemoteAddr(), "<====>", wlan.RemoteAddr(), "CANCEL")
		}()
	}
	Nat(wlan, lan)
}

// 运行nat服务
func Nat(wlan, lan io.ReadWriteCloser) {
	closed := false
	lastUpdate := time.Now().Unix()
	closeIO := func() {
		if closed {
			return
		}
		closed = true
		lan.Close()
		wlan.Close()
	}

	go func() {
		for !closed && routine.IsRunning() {
			t := time.Now().Unix() - 1200
			if lastUpdate < t {
				break
			}
			routine.Sleep(2000)
		}
		closeIO()
	}()

	go func() {
		buf := make([]byte, bufSize)
		for routine.IsRunning() {
			n, err := lan.Read(buf)
			if err != nil {
				logs.Info("lan", err)
				break
			}
			if n != 0 {
				lastUpdate = time.Now().Unix()
				_, err = wlan.Write(buf[:n])
				//log.Println("Read:", string(buf[:n]))
				if err != nil {
					logs.Info("wan", err)
					break
				}
			}
		}
		closeIO()
	}()

	buf := make([]byte, bufSize)
	for routine.IsRunning() {
		n, err := wlan.Read(buf)
		if err != nil {
			break
		}
		if n > 0 {
			lastUpdate = time.Now().Unix()
			_, err = lan.Write(buf[:n])
			//log.Println("write:", string(buf[:n]))
			if err != nil {
				break
			}
		}
	}
	closeIO()
}
